package de.unimannheim.ki.usermanagement;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import de.umass.lastfm.Track;
import de.unimannheim.ki.databaseentities.MusicObject;
import de.unimannheim.ki.databaseentities.Musicuser;
import de.unimannheim.ki.databaseentities.Song;
import de.unimannheim.ki.databaseentities.UserEvaluation;
import de.unimannheim.ki.servlets.JsonEvaluateAnswer;
import de.unimannheim.ki.servlets.JsonEvaluateElem;

public class DatabaseUserDAO {
	 private static final String PERSISTENCE_UNIT_NAME = "my-music-search";
	 private EntityManagerFactory factory;
	 private static DatabaseUserDAO dudao= null;
	 private   EntityManager em;
	 public static DatabaseUserDAO getDAO(){
		 if(dudao == null){
			 dudao = new DatabaseUserDAO();
		 } 
		 
		 return dudao;
	 }
	 
	 private DatabaseUserDAO(){
		 factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
		 em = factory.createEntityManager();
	 }
	 
	 public boolean hasUser(String fbid){
		 System.out.println("ENTERED");
		 Query q = em.createQuery("select t from Musicuser t where  t.fbid = "+fbid+" and t.firstname IS NOT NULL" );
		 return q.getResultList().size() != 0;
	 }
	 public boolean hasUserwithoutlastfm(String fbid){
		 Query q = em.createQuery("select t from Musicuser t where t.fbid = '"+fbid+"'" );
		 
		 return q.getResultList().size() != 0;
	 }
	 public  Musicuser getUser(String fbid){
		 	Query q = em.createQuery("select t from Musicuser t where t.fbid = "+fbid);
		    List<Musicuser> userList = q.getResultList();
		    for (Musicuser tmp : userList) {
		      return tmp;
		    }
		    return null;
	 }
	/* public Song getSong(String id){
		 	Query q = em.createQuery("select t from Song t where t.id = "+id);
		    List<Song> songList = q.getResultList();
		    for (Song tmp : songList) {
		      return tmp;
		    }
		    return null;
	 }*/
	 
	 public  List<Musicuser> getAllUsers(){
		    Query q = em.createQuery("select t from Musicuser t");
		    List<Musicuser> userList = q.getResultList();
		    return userList;
	 }
	 
	 public  List<Musicuser> getAllUserswithLastfm(){
		    Query q = em.createQuery("select t from Musicuser t where t.lastfmid IS NOT NULL");
		    List<Musicuser> userList = q.getResultList();
		    return userList;
	 }
	 public  List<Musicuser> getAllUserswithoutLastfm(){
		    Query q = em.createQuery("select t from Musicuser t where t.lastfmid IS NULL");
		    List<Musicuser> userList = q.getResultList();
		    return userList;
	 }
	 public  List<Song> getAllSongs(){
		    Query q = em.createQuery("select t from Song t");
		    List<Song> songList = q.getResultList();
		    return songList;
	 }
	 
	 public  List<Song> getSongsforUser(String fbid){
		 Query q = em.createQuery("select t from Musicuser t where t.fbid ="+fbid);
		 return ((Musicuser) q.getSingleResult()).getSongs();
	 }
	 
	 public boolean songExists(String songid){
		return em.find(Song.class, songid) != null;
	 }
	 
	 public Song getSong(String songid){
			return em.find(Song.class, songid);
	 }
	 
	 public boolean objectExits (String objectname){
		 Query q = em.createQuery("select t from MusicObject t where t.name ="+ "'"+objectname+"'");
		 return (q.getResultList().size() != 0);
	 }
	 
	 
	 public MusicObject getObject(String objectname){
		 Query q = em.createQuery("select t from MusicObject t where t.name ="+ "'"+objectname+"'");
		 return (MusicObject) q.getResultList().get(0);
	 }
	 public List<MusicObject> getAllObjects(){
		 	Query q = em.createQuery("select t from MusicObject t");
		    List<MusicObject> objectList = q.getResultList();
		    return objectList;
	 }
	 
	 public void persistNewUser(FbUser user) {
		 List<MusicObject> objects= new ArrayList<MusicObject>();
		 	String[] splitter = user.getMusic().split(",");
		 	MusicObject object = null;
		 	
		 	for (String string : splitter) {
		 		//first check if the object is in the database
		 		if(string.trim().equals("")) continue;
		 		if(string.contains("'")) continue;
		 		string.replace("'", " ");
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 			if(objects.contains(object)) continue;
		 		} else {
		 			object = new MusicObject();
		 			string.replace("'", " ");
			 		object.setName(string.trim());
			 		object.setType("music");
		 		}
				objects.add(object);
			}
		 	
		 	 splitter = user.getMovies().split(",");
		 	 
		  	for (String string : splitter) {
		  		if(string.trim().equals("")) continue;
		  		if(string.contains("'")) continue;
		 		//first check if the object is in the database
		  		string.replace("'", " ");
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 			if(objects.contains(object)) continue;
		 		} else {
		 			object = new MusicObject();
		 			string.replace("'", " ");
			 		object.setName(string.trim());
			 		object.setType("movies");
		 		}
				objects.add(object);
			}
		 	
		  	
		 	 splitter = user.getBooks().split(",");
		  	
		 	 for (String string : splitter) {
		 		if(string.trim().equals("")) continue;
		 		if(string.contains("'")) continue;
		 		//first check if the object is in the database
		 		string.replace("'", " ");
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 			if(objects.contains(object)) continue;
		 		} else {
		 			object = new MusicObject();
		 			string.replace("'", " ");
			 		object.setName(string.trim());
			 		object.setType("books");
		 		}
				objects.add(object);
			}
		 	
		 	 
		 	 splitter = user.getTv().split(",");
		 	 
		  	for (String string : splitter) {
		  		if(string.trim().equals("")) continue;
		  		if(string.contains("'")) continue;
		 		//first check if the object is in the database
		  		string.replace("'", " ");
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 			if(objects.contains(object)) continue;
		 		} else {
		 			object = new MusicObject();
		 			string.replace("'", " ");
			 		object.setName(string.trim());
			 		object.setType("tv");
		 		}
				objects.add(object);
			}
		  	em.getTransaction().begin();
		 	
		 	//build up user
		    Musicuser muser = new Musicuser();
		    //set parameters
		    muser.setFbid(user.getUid());
		    // TODO change to parameter
		    muser.setAge(20);
		    muser.setFirstname(user.getFirst_name());
		    
		    muser.setName(user.getLast_name());
		    muser.setObjects(objects);
		
		    //Persist data
		    em.persist(muser);
		    em.getTransaction().commit();
		    // Transaction is done	
		 	
	 }
	 
	 
	 public void persistNewUser(FbUser user, List<Track> tracks, String lastfmid){
		 
		 	// Build up songlist
		 	List<Song> songs = new ArrayList<Song>();
		 	Song song = null;
		 	//Convert Track list to Song list
		  	for (Track track : tracks) {
		  		//first check if the song is in the database
		  		if(songExists(track.getUrl())) {
		  			song = getSong(track.getUrl());
		  		} else {
		  			song = new Song();
		  			
		  			if(track.getUrl() == null || track.getUrl().equals("")){
		  				continue;
		  			}else {
		  				song.setId(track.getId());
		  			}
		  			song.setId(track.getUrl());
		  			song.setInterpret(track.getArtist());
		  			song.setName(track.getName());
		  			song.setGenre("music");
		  		}
		  		songs.add(song);
			}
		  	
		  	
			// Build up objectlist
			List<MusicObject> objects= new ArrayList<MusicObject>();
		  	if( ! this.hasUserwithoutlastfm(user.getUid().trim())){
		  		System.out.println("TEST TEST TEST TEST TEST");	
		 	String[] splitter = user.getMusic().split(",");
		 	MusicObject object = null;
		 	
		 	for (String string : splitter) {
		 		//first check if the object is in the database
		 		if(string.trim().equals("")) continue;
		 		
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 		} else {
		 			object = new MusicObject();
			 		object.setName(string.trim());
			 		object.setType("music");
		 		}
				objects.add(object);
			}
		 	
		 	 splitter = user.getMovies().split(",");
		 	 
		  	for (String string : splitter) {
		  		if(string.trim().equals("")) continue;
		 		//first check if the object is in the database
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 		} else {
		 			object = new MusicObject();
			 		object.setName(string.trim());
			 		object.setType("movies");
		 		}
				objects.add(object);
			}
		 	
		  	
		 	 splitter = user.getBooks().split(",");
		  	
		 	 for (String string : splitter) {
		 		if(string.trim().equals("")) continue;
		 		//first check if the object is in the database
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 		} else {
		 			object = new MusicObject();
			 		object.setName(string.trim());
			 		object.setType("books");
		 		}
				objects.add(object);
			}
		 	
		 	 
		 	 splitter = user.getTv().split(",");
		 	 
		  	for (String string : splitter) {
		  		if(string.trim().equals("")) continue;
		 		//first check if the object is in the database
		 		if(objectExits(string.trim())){
		 			object = getObject(string.trim());
		 		} else {
		 			object = new MusicObject();
			 		object.setName(string.trim());
			 		object.setType("tv");
		 		}
				objects.add(object);
			}
		  	}
		 	 
		 	 
		 	// Begin database transaction
		 	em.getTransaction().begin();
		 	
		 	
		 	
		 	
		 	Musicuser muser = null;
		 	//build up user
		 	boolean refresh = false;
		 	if(this.hasUserwithoutlastfm(user.getUid())){
		 		muser =  this.getUser(user.getUid());
		 		refresh = true;
		 	}else {
		 		muser = new Musicuser();
		 	}
		 	
		 	
		 	
		    //set parameters
		    muser.setFbid(user.getUid());
		    muser.setLastfmid(lastfmid);
		    // TODO change to parameter
		    muser.setAge(20);
		    muser.setFirstname(user.getFirst_name());
		    
		    muser.setName(user.getLast_name());
		    if(!refresh) muser.setObjects(objects);
		    muser.setSongs(songs);
		    //Persist data
		    if(!refresh){
		
		    	em.persist(muser);
		    } else {
		    	//em.refresh(muser);
		    }
		    em.getTransaction().commit();
		    // Transaction is done
	 }
	 public void refreshUser (Musicuser mu){
			try{
		 	em.getTransaction().begin();
			em.merge(mu);
			em.getTransaction().commit();
			} catch (Exception e){
				e.printStackTrace();
			}
	 }
	 
	 public void persistRating(Musicuser mu, JsonEvaluateAnswer jea){
		
			List<JsonEvaluateElem> elemList = jea.getEval_array();
			List<UserEvaluation> dbevalList = new ArrayList<UserEvaluation>();
			UserEvaluation dbeval = null;
			for (JsonEvaluateElem jsonEvaluateElem : elemList) {
				dbeval = new UserEvaluation();
				dbeval.setMusicuser(mu);
				dbeval.setRating(jsonEvaluateElem.getScore());
				dbeval.setSubject(jsonEvaluateElem.getSubject());
				dbevalList.add(dbeval);
			}
			mu.setEvaluations(dbevalList);
			em.getTransaction().begin();
			em.persist(mu);
			em.getTransaction().commit();
		}
}


